# 建造者模式生成专属用户训练计划
from abc import ABC,abstractmethod
from report.models import WorkoutPlan,WorkoutPlanExercise,UserWorkoutHistory,Exercise

# 在录音的最后，hi按早着模式在我的功能中的体现有讲，主要是结合唉大模型+建造者模式生成训练计划，建造者模式在我的项目中起到了数据处理+存储的重要作用
# 建造者的有点就是能讲复杂的要求进行分解，具体在ai生成计划结果后，返回的数据结构是就是提示词说的结构，但我需要讲他写入表中
# 如果是自己处理，必须进行一步步的数据转换，但是建造者他可以利用自身儿处理复杂逻辑的有点，直接吧所有的逻辑都进行处理，
# 而且后期很方便进行管理，直接在build方法中直接修改逻辑也不会影响整体运作，也具有很强的灵活性
# 抽象建造者
class WorkoutPlanBuilder(ABC):
    @abstractmethod
    def set_title(self, title):
        pass

    @abstractmethod
    def set_description(self, description):
        pass

    @abstractmethod
    def set_difficulty(self, difficulty):
        pass

    @abstractmethod
    def set_total_duration(self, duration):
        pass

    @abstractmethod
    def set_rest_time(self, rest_time):
        pass

    @abstractmethod
    def add_exercise(self, exercise, sets=3, reps=10, order=0):
        pass

    @abstractmethod
    def build(self):
        pass


# 具体建造者
class ConcreteWorkoutPlanBuilder(WorkoutPlanBuilder):
    def __init__(self, user):
        self.user = user
        self.workout_plan = WorkoutPlan(created_by=user)
        self.exercises = []

    def set_title(self, title):
        self.workout_plan.title = title
        return self

    def set_description(self, description):
        self.workout_plan.description = description
        return self

    def set_difficulty(self, difficulty):
        self.workout_plan.difficulty = difficulty
        return self

    def set_total_duration(self, duration):
        self.workout_plan.total_duration = duration
        return self

    def set_rest_time(self, rest_time):
        self.workout_plan.rest_time = rest_time
        return self

    def add_exercise(self, exercise, sets=3, reps=10, order=0):
        self.exercises.append({
            'exercise': exercise,
            'sets': sets,
            'reps': reps,
            'order': order
        })
        return self

    def build(self):  # 朱哟的构建方法，复杂逻辑都在此进行处理
        # 添加验证
        if not self.workout_plan.title:
            raise ValueError("计划必须包含标题")

        if not self.exercises:
            raise ValueError("计划必须包含至少一个动作")

        # 计算总时长：因为我的比欧中有这个字段，它是需要进行一个计算的逻辑，在建造者中可以直接处理好，不需要你后期手动 处理
        total_duration = 0
        for exercise_data in self.exercises:
            exercise = exercise_data['exercise']
            sets = exercise_data['sets']
            total_duration += exercise.estimated_duration * sets

        # 加上休息时间：总训练时间=训练时间+休息时间*(动作数-1)
        total_duration += self.workout_plan.rest_time * (len(self.exercises) - 1)
        self.workout_plan.total_duration = total_duration

        # 保存计划
        self.workout_plan.save()

        # 添加动作到计划
        for order, exercise_data in enumerate(self.exercises):
            WorkoutPlanExercise.objects.create(
                workout_plan=self.workout_plan,
                exercise=exercise_data['exercise'],
                sets=exercise_data['sets'],
                reps=exercise_data['reps'],
                order=order
            )
        return self.workout_plan


# 本身是有指挥者的，但他是可以选择的，所以介入了ai，ai代替了他
# 指挥者==>负责指导和管理健身计划的构建过程
# class WorkoutPlanDirector:
#     def __init__(self, builder: WorkoutPlanBuilder):
#         self.builder = builder
#
#     def construct_beginner_plan(self, user_history):
#         # 基于用户历史数据构建初级计划
#         favorite_exercises = self._analyze_user_history(user_history)
#
#         plan = (self.builder
#                 .set_title("新手入门训练计划")
#                 .set_description("专为您定制的新手友好型训练计划")
#                 .set_difficulty('beginner')
#                 .set_rest_time(45))
#
#         # 添加用户偏好的动作
#         for i, exercise in enumerate(favorite_exercises[:4]):  # 最多4个动作
#             plan.add_exercise(exercise, sets=2, reps=8, order=i)
#
#         return plan.build()
#
#     def construct_intermediate_plan(self, user_history):
#         # 基于用户历史数据构建中级计划
#         favorite_exercises = self._analyze_user_history(user_history)
#
#         plan = (self.builder
#                 .set_title("中级强化训练计划")
#                 .set_description("挑战自我的中级训练计划")
#                 .set_difficulty('intermediate')
#                 .set_rest_time(30))
#
#         for i, exercise in enumerate(favorite_exercises[:6]):  # 最多6个动作
#             plan.add_exercise(exercise, sets=3, reps=12, order=i)
#
#         return plan.build()
#
#     def _analyze_user_history(self, user_history):
#         # 分析用户历史数据，返回最常做的动作
#         from collections import Counter
#         exercise_counter = Counter()
#
#         for history in user_history:
#             exercise_counter[history.exercise] += history.performance_score
#
#         # 返回评分最高的动作
#         return [exercise for exercise, score in exercise_counter.most_common(10)]
